#pragma once

#include <glog/logging.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/service.h>
#include <memory>
#include <muduo/base/Timestamp.h>
#include <muduo/net/Buffer.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/InetAddress.h>
#include <muduo/net/TcpConnection.h>
#include <muduo/net/TcpServer.h>
#include <string>
#include <unordered_map>

namespace RPC
{
    /**
     * @brief 这个类是我编写的这个框架专门用来发布RPC服务的网络对象类
     *
     */
    class MyRpcProvider
    {
    public:
        // 这里是框架提供给外部使用的，可以发布rpc方法的函数接口
        void NotifyService( google::protobuf::Service *service );

        // 启动rpc服务节点，开始提供rpc远程网络调用服务
        void Run( int nodeIndex, short port );

        ~MyRpcProvider();

    private:
        void OnConnection( const std::shared_ptr< muduo::net::TcpConnection > &conn );  // 新的socket连接回调
        // 这是已建立连接用户的读写事件回调
        void OnMessage( const std::shared_ptr< muduo::net::TcpConnection > &conn, muduo::net::Buffer *buffer, muduo::Timestamp );
        // Closure的回调操作，用于序列化rpc的响应和网络发送
        void SendRpcResponse( const muduo::net::TcpConnectionPtr &, google::protobuf::Message * );

    private:
        muduo::net::EventLoop m_eventLoop;
        std::shared_ptr< muduo::net::TcpServer > m_muduo_server;
        // 这个结构体里面是存放一种服务有哪些方法的
        struct ServiceInfo
        {
            google::protobuf::Service *m_servie;                                                        // 保存服务对象
            std::unordered_map< std::string, const google::protobuf::MethodDescriptor * > m_methodMap;  // 这是保存方法描述符的
        };

        // 还需要存储已经注册了的服务对象和其方法的所有信息
        std::unordered_map< std::string, ServiceInfo > m_service_map;  // 这个容器就是保存我们有多少个服务的
    };
}  // namespace RPC
